import axios from "axios";
import notification from "ant-design-vue/es/notification";
import store from "@/store";
import { VueAxios } from "./axios";
import { CheckRefrshToken } from "../cacheInstanceUtils/accessToken";
import { getAccessToken } from "../cacheInstanceUtils/accessTokenCache";

// http状态码信息
const httpCode = {
  ok: 200,
  waring: 203,
  error: 300,
  badRequest: 400,
  unauthorized: 401,
  forbidden: 403,
  notFound: 404,
  menthodNotAllowed: 405,
  internalServerError: 500,
};

// 创建axios实例，在这里可以设置请求的默认配置
const service = axios.create({
  timeout: 3000 * 10, // 设置超时时间30秒
  baseURL: process.env.VUE_APP_API_BASE_URL,
});

// 统一设置post请求头
service.defaults.headers.post["Content-Type"] =
  "application/json;charset=UTF-8"; //'application/x-www-form-urlencoded'

/**
 *
 * @param {error,success,warning,warn,info,open} type
 * @param {消息頭} message
 * @param {消息内容} description
 * @param {超時時間，默認5S，單位：秒} duration
 */
let openNotification = (type, message, description, duration = 5) => {
  // const key = `open${Date.now()}`;
  notification[type]({
    duration: duration,
    message: message,
    onClose: close,
    description: (h) => {
      return description;
    },
    // btn: h => {
    // 	return h(
    // 		'a-button',
    // 		{
    // 			props: {
    // 				type: 'primary',
    // 				size: 'small',
    // 			},
    // 			on: {
    // 				click: () => notification.close(key),
    // 			},
    // 		},
    // 		'Confirm',
    // 	);
    // },
    // key,
  });
};

// 全局异常处理
let err = (error) => {
  // 请求超时处理
  if (error.code == "ECONNABORTED" && error.message.indexOf("timeout") != -1) {
    openNotification(
      "error",
      "系统异常",
      ((error.response || {}).data || {}).message || "请求超时，请稍后重试"
    );
    return Promise.reject(error);
  }

  const response = error.response;
  const status = response?.status;
  const data = response?.data;
  // 根据请求失败的http状态码去给用户相应的提示
  switch (status) {
    case httpCode.unauthorized:
      // 401 未授权
      if (getAccessToken()) {
        // 如果有token，说明token已过期
        openNotification("warning", "登录已过期", "请重新登录", 3);
        store.dispatch("user/logout").then(() => {
          // 延迟跳转到登录页
          setTimeout(() => {
            window.location.href = "/auth/login";
          }, 1500);
        });
      } else {
        // 如果没有token，说明未登录
        openNotification("warning", "未登录", "请先登录", 3);
        window.location.href = "/auth/login";
      }
      return Promise.reject(error);
      break;

    case httpCode.forbidden:
      // 403 禁止访问
      openNotification("error", "禁止访问", "您没有权限访问此资源", 3);
      break;

    case httpCode.notFound:
      // 404 资源不存在
      openNotification("error", "资源不存在", "请求的资源不存在或已被删除", 3);
      break;

    case httpCode.internalServerError:
      // 500 服务器错误
      openNotification("error", "服务器错误", "服务器内部错误，请稍后重试", 3);
      break;

    default:
      // 其他错误
      const errorMessage = data?.message || error.message || "请求失败，请稍后重试";
      openNotification("error", "请求失败", errorMessage, 3);
  }

  if (error.code === 'ERR_NETWORK') {
     // 500 服务器错误
     openNotification("error", "服务器错误", "服务器请求失败，请稍后重试", 3);
  }
  return Promise.reject(error);
};

/** 添加请求拦截器 **/
service.interceptors.request.use((config) => {
  // 如果不是请求的mock，则改变请求地址
  // if (!config.headers.isMock) {
  // 	config.baseURL = baseUrl
  // }
  // 判断token是否存在
  let token = getAccessToken();
  if (token) {
    // 在请求头携带token进行请求
    config.headers["Authorization"] = "Bearer " + token;
  }
  // 导出文件的接口，返回的是二进制流，设置请求响应类型为blob
  if (config.url) {
    if (config.url.includes("/download")) {
      config.headers["responseType"] = "blob";
    }
    // 文件上传，发送的是二进制流，所以需要设置请求头的'Content-Type'
    if (config.url.includes("file/upload")) {
      config.headers["Content-Type"] = "multipart/form-data";
    }
  }
  // 判断访问token是否即将过期 并且请求地址不是刷新token的地址
  return CheckRefrshToken(config);
}, err);

/** 添加响应拦截器 **/
service.interceptors.response.use((response) => {
  let { status, statusText, config } = response;
  if (status === 200) {
    let { msg, code } = response.data;
    if (config.url.includes("/export") || config.url.includes("/download")) {
      return response;
    } else if (code === httpCode.ok || code === httpCode.waring) {
      return response.data;
    } else if (code === httpCode.unauthorized) {
      // 处理业务层面的未授权
      if (getAccessToken()) {
        openNotification("warning", "登录已过期", "请重新登录", 3);
        store.dispatch("user/logout").then(() => {
          setTimeout(() => {
            window.location.href = "/auth/login";
          }, 1500);
        });
      }
      return Promise.reject(msg);
    } else {
      // 其他业务错误
      openNotification("error", "操作失败", msg || "操作失败，请稍后重试", 3);
      return Promise.reject(msg);
    }
  } else {
    openNotification("error", "系统异常", statusText || "服务器异常", 3);
    return Promise.reject(statusText);
  }
}, err);

/* 统一封装post请求 */
export const post = (url, data, config = {}) => {
  return new Promise((resolve, reject) => {
    service({
      method: "post",
      url,
      data,
      ...config,
    })
      .then((response) => {
        resolve(response);
      })
      .catch((error) => {
        reject(error);
      });
  });
};

/* 统一封装get请求 */
export const get = (url, params, config = {}) => {
  return new Promise((resolve, reject) => {
    let restfulAPI = false;
    // 如果 params 是对象
    // if (params && typeof params === "object" && !Array.isArray(params)) {
    // }
    // 如果 params 不是对象，则由调用者自行处理 URL
    if (params && typeof params !== "object") {
      // 这里可以根据需要抛出错误或直接使用原始 URL
      url += "/" + params;
      restfulAPI = true;
    }
    // 添加时间戳参数，防止浏览器（IE）对 GET 请求的缓存
    url +=
      (url.includes("?") ? "&" : "?") + "t=" + new Date().getTime().toString();

    service({
      method: "get",
      url: url,
      params: restfulAPI ? undefined : params,
      ...config,
    })
      .then((response) => {
        resolve(response);
      })
      .catch((error) => {
        reject(error);
      });
  });
};

/* 统一封装put请求  处理结果 */
export const put = (url, data, config = {}) => {
  return new Promise((resolve, reject) => {
    // 判断 data 是否存在 id 字段，且 id 不为空
    if (data && data.id) {
      url = `${url}/${data.id}`; // 拼接 id 到 url
    }
    service({
      method: "put",
      url,
      data,
      ...config,
    })
      .then((response) => {
        resolve(response);
      })
      .catch((error) => {
        reject(error);
      });
  });
};

/* 统一封装put请求  处理结果 */
export const del = (url, data, config = {}) => {
  return new Promise((resolve, reject) => {
    // 判断 data 是否是数组且不为空
    if (Array.isArray(data) && data.length > 0) {
      // 过滤掉无效值（如空字符串、null、undefined）
      const validIds = data.filter((id) => id != null && id !== "");
      if (validIds.length > 0) {
        url = `${url}/${validIds.join(",")}`; // 将有效值拼接成逗号分隔的字符串,将拼接后的字符串拼接到 url 后面
      }
    }
    service({
      method: "delete",
      url,
      data,
      ...config,
    })
      .then((response) => {
        resolve(response);
      })
      .catch((error) => {
        reject(error);
      });
  });
};

// 上传文件
export const postFile = (url, data, config = {}) => {
  return new Promise((resolve, reject) => {
    service({
      method: "post",
      url,
      data: data,
      ...config,
    })
      .then((response) => {
        resolve(response);
      })
      .catch((error) => {
        reject(error);
      });
  });
};

// 导出excel
export function postExportExcel(url, data) {
  return service({
    method: "post",
    responseType: "blob",
    url: url,
    data: data,
  })
    .then((res) => {
      let fileName = "";
      let val = res.data;
      if (val !== null) {
        fileName = res.headers["content-disposition"]
          .split(";")[1]
          .split("filename=")[1];
      }
      let blob = new Blob([val]);
      if (window.navigator.msSaveOrOpenBlob) {
        navigator.msSaveBlob(blob, fileName);
      } else {
        let link = document.createElement("a");
        link.href = window.URL.createObjectURL(blob);
        link.download = fileName;
        // link.style.display = 'none'
        // link.href = URL.createObjectURL(blob)
        // link.setAttribute('download', fileName + '.xlsx')
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
      }
    })
    .catch((e) => {
      openNotification("error", "系统异常", e.message || "服务器异常");
    });
}

// 文件上传，发送的是二进制流，所以需要设置请求头的'Content-Type'
// if (config.url.includes('/upload')) {
//   config.headers['Content-Type'] = 'multipart/form-data'
// }

// response.headers['content-type'].includes("application/vnd.ms-excel")

// export function postImportExcel(url, formData) {
//   return service({
//     method: 'post',
//     url: url,
//     data: formData
//   })
//     .then(val => {

//     });
// }

const installer = {
  vm: {},
  install(vue) {
    vue.use(VueAxios, service);
  },
};
export { installer as VueAxios, service as axios };
